home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / Libraries / Graphic Elements 3 / GEQTHack / GEQTHack.c < prev   
C/C++ Source or Header  |  1995-08-28  |  14KB  |  619 lines

  1. /*
  2.     GEQTHack.c
  3.     
  4.     QuickTime Movie as a Graphic Element -- demo
  5.     
  6.     6/10/95
  7.     
  8.     by Al Evans
  9.     
  10. */
  11.  
  12. #include <Movies.h>
  13.  
  14. #include "GUtilities.h"
  15. #include "GrowWindConst.h"
  16. #include "GraphElements.h"
  17. #include "Rects.h"
  18. #include "GridElement.h"
  19. #include "GEBalls.h"
  20. #include "Meter.h"
  21. #include "GELogo.h"
  22. #include "GEMovie.h"
  23. #include "GEAbout.h"
  24.  
  25. // Adding sounds
  26. #include "GESound.h"
  27.  
  28. // Menu Commands
  29.  
  30. #define    rMenuBar                128        /* application's menu bar */
  31.  
  32. #define    mApple                    128        /* Apple menu */
  33. #define    iAbout                    1
  34.  
  35. #define    mFile                    129        /* File menu */
  36. #define    iQuit                    1
  37.  
  38. #define    mEdit                    130        /* Edit menu */
  39. #define    iUndo                    1
  40. #define    iCut                    3
  41. #define    iCopy                    4
  42. #define    iPaste                    5
  43. #define    iClear                    6
  44.  
  45. #define mSpecial                131
  46. #define iTiming                    1
  47. #define iMeter                    2
  48. #define iSingleFrame            3
  49. #define iPlayMovie                4
  50. #define iSoundActive            5
  51.  
  52. #define    rAboutDialog    228        
  53. #define rUserAlert        129
  54. #define rPerfAlert        300
  55.  
  56. // Background PICT resource number
  57. #define    rBkgPic 200
  58.  
  59. // Number of master pointer blocks needed
  60. #define masterBlocksNeeded 10
  61.  
  62. // Globals
  63. Boolean        gFinished;
  64. WindowPtr    gAnimWindow;
  65. Boolean        gSingleFrame = false;
  66. Boolean        gDoOne = false;
  67. Boolean        gMeterShown = true;
  68. Rect        gWorldBaseRect;
  69. Rect        gWorldLimRect;
  70. Boolean        gMoviePlaying;
  71. Boolean        gSoundActive;
  72.  
  73. // Performance measurement
  74.  
  75. #define thirtySeconds 30L * 1000 * 1000        //µsec for timers -- never time out
  76.  
  77. TMTask    gTTimeTask, gATimeTask;
  78. unsigned long gTotalTime = 0, gAnimTime = 0;
  79.  
  80. // Forward declarations
  81.  
  82. Boolean Initialize( void );
  83. void Shutdown(void);
  84. void EventLoop( void );
  85.  
  86. pascal void MaintainSounds(GEWorldPtr world, Ptr soundRec);
  87.  
  88. main()
  89. {
  90.     MaxApplZone();
  91.     if ( Initialize() )
  92.         EventLoop();
  93.     Shutdown();
  94. }
  95.  
  96. // Initialization and Shutdown
  97.  
  98. Boolean AdequateSystem(void)
  99. {
  100.     OSErr        err;
  101.     long        response;
  102.     Boolean        ok;
  103.     
  104.     //We need 68020 or better
  105.     err = Gestalt(gestaltProcessorType, &response);
  106.     ok = (!err) & (response >= gestalt68020);
  107.     
  108.     //We need System 7 or later
  109.     err = Gestalt(gestaltSystemVersion, &response);
  110.     ok = (!err) & (((response & 0xFFFF) / 256) >= 7);
  111.     
  112.     //We need color QD & offscreen GWorlds
  113.     err = Gestalt(gestaltQuickdrawVersion, &response);
  114.     ok = ok & (!err) & (response >= gestalt32BitQD);
  115.     err = Gestalt(gestaltQuickdrawFeatures, &response);
  116.     ok = ok & (!err) & (response >= 3);         //hasColor & deep GWorlds
  117.     
  118.     return ok;
  119.     
  120. }
  121.  
  122. // Make window centered on main graphic device
  123. WindowPtr MakeWindow(short wHSize, short wVSize)
  124. {
  125.     GDHandle    mainDevice;
  126.     Rect        devRect;
  127.     short        hOffst, vOffst;
  128.     Rect        windRect;
  129.     
  130.     mainDevice = GetMainDevice();
  131.     devRect = (**mainDevice).gdRect;
  132.     gWorldLimRect.top = wVSize / 2;
  133.     gWorldLimRect.left = wHSize / 2;
  134.     gWorldLimRect.bottom = RectHeight(&devRect);
  135.     gWorldLimRect.right = RectWidth(&devRect);
  136.     hOffst = (devRect.right - devRect.left - wHSize) / 2;
  137.     if (hOffst < 0) hOffst = 0;
  138.     vOffst = (devRect.bottom - devRect.top - wVSize) / 2;
  139.     if (vOffst < 0 ) vOffst = 0;
  140.     windRect.left = hOffst;
  141.     windRect.right = hOffst + wHSize;
  142.     windRect.top = vOffst;
  143.     windRect.bottom = vOffst + wVSize; 
  144.     
  145.     return NewCWindow(nil, &windRect, "\pQuickTime GE", false, documentProc,
  146.                         (WindowPtr) -1L, false, 0L);
  147. }
  148.  
  149. void InitPerformanceTiming(void)
  150. {
  151.     // Init Timers
  152.     gTTimeTask.tmAddr = nil;
  153.     gTTimeTask.tmWakeUp = 0;
  154.     gTTimeTask.tmReserved = 0;
  155.     
  156.     gATimeTask.tmAddr =  nil;
  157.     gATimeTask.tmWakeUp = 0;
  158.     gATimeTask.tmReserved = 0;
  159.     
  160. }
  161.  
  162. Boolean LoadBackground(GEWorldPtr world)
  163. {
  164.     GrafElPtr    bkg;
  165.     if (bkg = NewGridPICT(world, 'BKG ', 1, rBkgPic, srcCopy, 0, 0, 128, 128))
  166.         return true;
  167.     return false;
  168. }
  169.  
  170. Boolean AddGrowBox(GEWorldPtr world)
  171. {
  172.     GrafElPtr    growBox;
  173.     
  174.     growBox = NewBasicPICT(world, 'GBOX', 32100, 20000, srcCopy, 
  175.                         gWorldBaseRect.right - 15, gWorldBaseRect.bottom - 15);
  176.     return (growBox != nil);
  177. }
  178.  
  179. Boolean InitializeGEWorld(WindowPtr window, 
  180.             Rect * refRect, Rect *actRect, GESoundPtr sounds)
  181. {
  182.  
  183.     Fixed        propH, propV;
  184.     Fixed        worldScale;
  185.     GEWorldPtr    animWorld;
  186.     
  187.     propH = (RectWidth(actRect) * 65536) / RectWidth(refRect);
  188.     propV = (RectHeight(actRect) * 65536) / RectHeight(refRect);
  189.     worldScale = (propH > propV?propH:propV);
  190.     
  191.     animWorld = NewGEWorld(window, refRect, worldScale , nil);
  192.     if (animWorld == nil) {
  193.         TellUser("\pCould not create new GEWorld.", 0);
  194.         return false;
  195.     }
  196.  
  197.     // Set for automatic sound maintenance
  198.     SetPostProcFunc(animWorld, MaintainSounds, (Ptr) sounds);
  199.  
  200.     if (!LoadBackground(animWorld)) {
  201.         TellUser("\pCould not load background", 0);
  202.         return false;
  203.     }
  204.     if (!InitBallGraphics(animWorld)) {
  205.         TellUser("\pCould not load test graphic", 0);
  206.         return false;
  207.     }
  208.  
  209.     if (!LoadUsageMeterScene(animWorld)) {
  210.         TellUser("\pCould not load usage meter", 0);
  211.         return false;
  212.     }
  213.     if (!LoadQTMovieScene(animWorld)) {
  214.         TellUser("\pCould not load QT movie", 0);
  215.         return false;
  216.     }
  217.     if (!LoadLogoScene(animWorld)) {
  218.         TellUser("\pCould not load GE logo", 0);
  219.         return false;
  220.     }
  221.     if (!AddGrowBox(animWorld)) {
  222.         TellUser("\pCould not add grow box", 0);
  223.         return false;
  224.     }
  225.     // Reposition meter a little to the left
  226.     MoveElement(animWorld, meterBkgID, -100, 0);
  227.     SetWRefCon(gAnimWindow, (long) animWorld);
  228.     gMoviePlaying = false;
  229.     return true;
  230. }
  231.  
  232. Boolean Initialize(void)
  233. {
  234.     
  235.     Rect        animRect;
  236.     GEWorldPtr    animWorld;
  237.     GESoundPtr    animWorldSounds;
  238.  
  239.     gFinished = false;
  240.     gSoundActive = true;
  241.     InitSystem(masterBlocksNeeded);
  242.  
  243.     EnterMovies();
  244.     
  245.     
  246.     if (!AdequateSystem()) {
  247.         TellUser("\pSorry, more powerful system required", 0);
  248.         return false;
  249.     }
  250.     if (!LoadMenus(rMenuBar)) {
  251.         TellUser("\pCould not load menus", 0);
  252.         return false;
  253.     }
  254.     
  255.     gAnimWindow = MakeWindow(512, 364);
  256.     if (gAnimWindow == nil) {
  257.         TellUser("\pCould not create window", 0);
  258.         return false;
  259.     }
  260.     animWorldSounds = GEInitSounds(4);
  261.     if (animWorldSounds == nil) {
  262.         TellUser("\pCould not initialize sounds", 0);
  263.         return false;
  264.     }
  265.     SetRect(&gWorldBaseRect, 0, 0, 512, 364);
  266.     animRect = gWorldBaseRect;
  267.     if (!InitializeGEWorld(gAnimWindow, &gWorldBaseRect, &animRect, animWorldSounds)) {
  268.         TellUser("\pCould not create animated world.", 0);
  269.         return false;
  270.     }
  271.     
  272.     InitPerformanceTiming();
  273.     
  274.     ActivateWorld((GEWorldPtr) GetWRefCon(gAnimWindow), true);
  275.     ShowWindow(gAnimWindow);
  276.     return true;
  277. }
  278.  
  279. void Shutdown(void)
  280. {
  281.     GEWorldPtr world = (GEWorldPtr) GetWRefCon(gAnimWindow);
  282.  
  283.     if (world) {
  284.         if (world->userData)
  285.             GEDisposeSounds((GESoundPtr) world->userData);
  286.         DisposeGEWorld(world);
  287.     }
  288.     ExitToShell();
  289. }
  290.  
  291. // Actions
  292.  
  293. void ChangeWorldSize(WindowPtr window, short newWidth, short newHeight)
  294. {
  295.     Rect    animRect;
  296.     GEWorldPtr world = (GEWorldPtr) GetWRefCon(window);
  297.     
  298.     // Save sounds Ptr
  299.     GESoundPtr  sounds = (GESoundPtr) world->userData;
  300.     
  301.     DisposeGEWorld(world);
  302.     SetRect(&animRect, 0, 0, newWidth, newHeight);
  303.     if (!InitializeGEWorld(window, &gWorldBaseRect, &animRect, sounds)) {
  304.         TellUser("\pCould not resize animated world.", 0);
  305.         ExitToShell();
  306.     }
  307.     world = (GEWorldPtr) GetWRefCon(window);
  308.  
  309.     ActivateWorld(world, true);
  310.  
  311. }
  312.  
  313. pascal void MaintainSounds(GEWorldPtr world, Ptr soundRec)
  314. {
  315.     GESoundMaintenance((GESoundPtr) soundRec);
  316. }
  317.  
  318. void RunMeterAnimation(short ms)
  319. {
  320.     static short    setting = 0;
  321.     
  322.     if (gMeterShown && (ms > 1)) {
  323.         if (ms == setting)
  324.             return;
  325.         if (ms > setting)
  326.             setting++;
  327.         else
  328.             if (ms < setting)
  329.                 setting--;
  330.         SetMeterReading((GEWorldPtr) GetWRefCon(gAnimWindow), 2 * setting);
  331.     }
  332.     
  333. }
  334.  
  335. void DisplayPerformance(long frames, long seconds)
  336. {
  337.     Str255 framesString, secondsString, fpsString;
  338.     long fps;
  339.     
  340.     NumToString(frames, framesString);
  341.     NumToString(seconds, secondsString);
  342.  
  343.     fps = (seconds > 0) ? frames / seconds : frames;
  344.     NumToString(fps, fpsString);
  345.  
  346.     ParamText(framesString, secondsString, fpsString, "\p");
  347.     NoteAlert(rPerfAlert, nil);
  348. }
  349.  
  350. void SetUpdateInterval(GEWorldPtr world, short newInterval)
  351. {
  352.     short        ballCount;
  353.     GrafElPtr    aBall;
  354.     
  355.     for (ballCount = 0; ballCount < numberOfBalls; ballCount++) {
  356.         aBall = FindElementByID(world, firstRBID + ballCount);
  357.         if (aBall != nil)
  358.             aBall->changeIntrvl = newInterval;
  359.         aBall = FindElementByID(world, firstBBID + ballCount);
  360.         if (aBall != nil)
  361.             aBall->changeIntrvl = newInterval;
  362.     }
  363. }
  364.  
  365. void DoTimingLoop(void)
  366. {
  367.     long ticks;
  368.     unsigned long frames, seconds;
  369.     GEWorldPtr    world = (GEWorldPtr) GetWRefCon(gAnimWindow);
  370.     
  371.     SetUpdateInterval(world, 1);
  372.     StartGETimer(world);
  373.     ticks = TickCount();
  374.  
  375.     for (frames = 0; ((TickCount() - ticks) < (30 * 60)) && (!Button()); frames++) { 
  376.         DoWorldUpdate(world, false);
  377.     }
  378.     
  379.     seconds = ((TickCount() - ticks) / 60);
  380.     
  381.     DisplayPerformance(frames, seconds);
  382.     SetUpdateInterval(world, 33);
  383.     
  384. }
  385.  
  386. // Event Handling
  387.  
  388. void EventLoop( void )
  389. {
  390.     Boolean        gotEvent;
  391.     EventRecord    event;
  392.     
  393.     void DoEvent (EventRecord *event);
  394.     void AdjustCursor( void);
  395.     
  396.     do {
  397.         InsTime( (QElemPtr) &gTTimeTask);
  398.         InsTime( (QElemPtr) &gATimeTask);
  399.         PrimeTime( (QElemPtr) &gTTimeTask, -thirtySeconds);
  400.         if (!gSingleFrame || gDoOne) {
  401.             PrimeTime( (QElemPtr) &gATimeTask, -thirtySeconds);
  402.             DoWorldUpdate((GEWorldPtr) GetWRefCon(gAnimWindow), false);
  403.             RmvTime( (QElemPtr) &gATimeTask);
  404.             gAnimTime = (thirtySeconds + gATimeTask.tmCount) / 1000;
  405.             gDoOne = false;
  406.         }
  407.         AdjustCursor();
  408.         if (gotEvent = WaitNextEvent(everyEvent, &event, 0L, nil)) 
  409.             DoEvent(&event);
  410.         RmvTime( (QElemPtr) &gTTimeTask);
  411.         gTotalTime = (thirtySeconds + gTTimeTask.tmCount) / 1000; //milliseconds
  412.         RunMeterAnimation(gAnimTime);
  413.         
  414.     } while (!gFinished);
  415. }
  416.  
  417. void DoEvent (EventRecord *event)
  418. {
  419.     short        part;
  420.     WindowPtr    window;
  421.     char        key;
  422.     long        newWSize;
  423.     
  424.     //Prototypes
  425.     void AdjustMenus( void );
  426.     void DoMenuCommand(long menuResult);
  427.     void DoActivate(WindowPtr window, Boolean becomingActive);
  428.     void DoUpdate(WindowPtr window);
  429.     
  430.     switch ( event->what ) {
  431.         case mouseDown:
  432.             part = FindWindow(event->where, &window);
  433.             switch ( part ) {
  434.                 case inMenuBar:
  435.                     StopGETimer((GEWorldPtr) GetWRefCon(gAnimWindow));
  436.                     AdjustMenus();
  437.                     DoMenuCommand(MenuSelect(event->where));
  438.                     StartGETimer((GEWorldPtr) GetWRefCon(gAnimWindow));
  439.                     break;
  440.                 case inSysWindow:
  441.                     SystemClick(event, window);
  442.                     break;
  443.                 case inContent:
  444.                     if ( window != FrontWindow() ) 
  445.                         SelectWindow(window);
  446.                     if (MouseDownInSensor((GEWorldPtr) GetWRefCon(gAnimWindow), event->where))
  447.                         ;;
  448.                     break;
  449.                 case inDrag:
  450.                     DragWindow(window, event->where, &qd.screenBits.bounds);
  451.                     break;
  452.                 case inGrow:
  453.                     newWSize = GrowWindowConstrained(window, event->where, 
  454.                                             &gWorldLimRect, &gWorldBaseRect);
  455.                     SizeWindow(window, LoWord(newWSize), HiWord(newWSize), true);
  456.                     ChangeWorldSize(window, LoWord(newWSize), HiWord(newWSize));
  457.                     InvalRect(&((GrafPtr)window)->portRect);
  458.                     break;
  459.  
  460.             }
  461.             break;
  462.         case keyDown:
  463.             key = event->message & charCodeMask;
  464.             if ( event->modifiers & cmdKey ) {
  465.                 StopGETimer((GEWorldPtr) GetWRefCon(gAnimWindow));
  466.                 AdjustMenus();
  467.                 DoMenuCommand(MenuKey(key));
  468.                 StartGETimer((GEWorldPtr) GetWRefCon(gAnimWindow));
  469.             }
  470.             gDoOne = true;
  471.             break;
  472.         case activateEvt:
  473.             DoActivate((WindowPtr) event->message, (event->modifiers & activeFlag) != 0);
  474.             break;
  475.         case updateEvt:
  476.             DoUpdate((WindowPtr) event->message);
  477.             break;
  478.         case osEvt:
  479.             switch ((event->message >> 24) & 0x0FF) {
  480.                 case suspendResumeMessage:
  481.                     gInBackground = (event->message & resumeFlag) == 0;
  482.                     DoActivate(FrontWindow(), !gInBackground);
  483.                     break;
  484.             }
  485.             break;
  486.         }
  487. }
  488.  
  489. void DoActivate(WindowPtr window, Boolean becomingActive)
  490. {
  491. #pragma unused (window)
  492. #pragma unused (becomingActive)
  493.     //Could start and stop animation here
  494. }
  495.  
  496.  
  497. void DoUpdate(WindowPtr window)
  498. {
  499.     Rect geRect;
  500.     GEWorldPtr geWorld;
  501.  
  502.     if (window == gAnimWindow)
  503.     {
  504.         SetPort( (GrafPtr) window );        
  505.         BeginUpdate(window);
  506.         DoWorldUpdate((GEWorldPtr) GetWRefCon(gAnimWindow), true);
  507.         EndUpdate(window);
  508.     }
  509. }
  510.  
  511. void AdjustMenus( void )
  512. {
  513.     WindowPtr    window;
  514.     MenuHandle    menu;
  515.     
  516.     window = FrontWindow();
  517.     
  518.     menu = GetMHandle(mFile);
  519.     EnableItem(menu, iQuit);
  520.  
  521.     menu = GetMHandle(mEdit);
  522.     if (window = gAnimWindow) {
  523.         DisableItem(menu, iUndo);
  524.         DisableItem(menu, iCut);
  525.         DisableItem(menu, iCopy);
  526.         DisableItem(menu, iClear);
  527.         DisableItem(menu, iPaste);
  528.     }
  529.     else {
  530.         EnableItem(menu, iUndo);
  531.         EnableItem(menu, iCut);
  532.         EnableItem(menu, iCopy);
  533.         EnableItem(menu, iClear);
  534.         EnableItem(menu, iPaste);
  535.     }
  536.     menu = GetMHandle(mSpecial);
  537.     
  538.     // Set up special items!
  539.     EnableItem(menu, iTiming);
  540.     EnableItem(menu, iMeter);
  541.     CheckItem(menu, iMeter, gMeterShown);
  542.     EnableItem(menu, iPlayMovie);
  543.     CheckItem(menu, iPlayMovie, gMoviePlaying);
  544.     EnableItem(menu, iSoundActive);
  545.     CheckItem(menu, iSoundActive, gSoundActive);
  546. }
  547.  
  548. void DoMenuCommand(long menuResult)
  549. {
  550.     short        menuID;
  551.     short        menuItem;
  552.     Str255        daName;
  553.     short        daRefNum;
  554.  
  555.     menuID = HiWord(menuResult);
  556.     menuItem = LoWord(menuResult);
  557.     switch ( menuID ) {
  558.         case mApple:
  559.             switch ( menuItem ) {
  560.                 case iAbout:
  561.                     PutUpAboutBox((GEWorldPtr) GetWRefCon(gAnimWindow));
  562.                     break;
  563.                 default:            /* all other items in this menu are DAs */
  564.                     GetItem(GetMHandle(mApple), menuItem, daName);
  565.                     daRefNum = OpenDeskAcc(daName);
  566.                     break;
  567.             }
  568.             break;
  569.         case mFile:
  570.             if (menuItem == iQuit)
  571.                 gFinished = true;
  572.             break;
  573.         case mEdit:
  574.             (void) SystemEdit(menuItem-1);
  575.             break;
  576.         case mSpecial:
  577.             //Add special items
  578.             switch ( menuItem ) {
  579.                 case iTiming:
  580.                     DoTimingLoop();
  581.                     break;
  582.                 case iMeter:
  583.                     gMeterShown = !gMeterShown;
  584.                     ShowElement((GEWorldPtr) GetWRefCon(gAnimWindow), meterBkgID, gMeterShown);
  585.                     ShowElement((GEWorldPtr) GetWRefCon(gAnimWindow), meterIndID, gMeterShown);
  586.                     break;
  587.                 case iSingleFrame:
  588.                     gSingleFrame = !gSingleFrame;
  589.                     break;
  590.                 case iPlayMovie:
  591.                     gMoviePlaying = !gMoviePlaying;
  592.                     PlayGEMovie((GEWorldPtr) GetWRefCon(gAnimWindow), gMoviePlaying);
  593.                     break;
  594.                 case iSoundActive:
  595.                     {
  596.                     GEWorldPtr world = (GEWorldPtr) GetWRefCon(gAnimWindow);
  597.                     GESoundPtr sounds = (GESoundPtr) world->userData;
  598.                     gSoundActive = !gSoundActive;
  599.                     GEnableSound(sounds, gSoundActive);
  600.                     }
  601.                     break;
  602.             }
  603.             break;
  604.     }
  605.     HiliteMenu(0);
  606. }
  607.  
  608. void AdjustCursor( void )
  609. {
  610.     WindowPtr    window;
  611.     
  612.     window = FrontWindow();
  613.     
  614.     if ( (window == gAnimWindow) && (!gInBackground) ) {
  615.         SetCursor(&qd.arrow);
  616.     }
  617. }
  618.  
  619.